import React, { useEffect, useRef, useState } from 'react';
import {
  View,
  TouchableOpacity,
  Text,
  Platform,
  Image,
  ScrollView,
  Linking,
  Alert,
  DeviceEventEmitter
} from 'react-native';
import { ItemHRow, UpdateModal, SeekBar } from '../compoment';
import VersionNumber from 'react-native-version-number';
import { showMessage, hideMessage } from 'react-native-flash-message';
import { Buffer } from 'buffer';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { changeHadUpdate, disConnectDev } from '../store/device/actions';
import { bleModule, bleProtocol } from './bleConst';
import { BleEventType, BleState } from '../utils/type';
import RNFetchBlob from 'rn-fetch-blob';
import Spinner from 'react-native-loading-spinner-overlay';
import IdleTimerManager from 'react-native-idle-timer';
import { resetMap } from '../utils/devicesType';

function AboutPage({ navigation, deviceId, nameStr, headStr, allData, changeHadUpdate }) {

  const [csversion, setCsversion] = useState('unknown');
  const [upState, setUpState] = useState(0);
  const [upProgress, setUpProgress] = useState(0);
  const [resetProgress, setResetProgress] = useState(0);
  // const [updata, setUpdate] = useState('');
  const [updateArr, setUpdateArr] = useState([]);
  const [showSpinner, setShowSpinner] = useState(false);
  const setArrData = [
    {
      id: 's4',
      sv: csversion,
      unit: '',
      des: 'Controller Version',
      type: 3,
    },
    {
      id: 's1',
      sv: VersionNumber.appVersion,
      unit: '',
      des: 'App Version',
      type: 3,
    },
    {
      id: 's5',
      sv: '',
      unit: '',
      des: 'Update Controller',
      type: 2,
    },
    {
      id: 's6',
      sv: '',
      unit: '',
      des: 'Update App',
      type: 2,
    },
    {
      id: 's7',
      sv: '',
      unit: '',
      des: 'Personal Settings',
      type: 2,
    },
    {
      id: 's8',
      sv: '',
      unit: '',
      des: 'Help',
      type: 2,
    }];
  const [selIndex, setSelIndex] = useState(0);
  DeviceEventEmitter.addListener('readSuccess', () => {
    console.log('about page 读取软件版本号/n');
    bleModule['write']('0103FFEE0002942A', 0).then(() => { }).catch(err => {
      // alert('Sending failed');
    })
  })

  // didload  蓝牙获取版本    
  useEffect(() => {
    const updateValueListener = bleModule.addListener(
      BleEventType.BleManagerDidUpdateValueForCharacteristic,
      handleUpdateValue,
    );
    const loadVersion = async () => {
      await fun3();
      console.log('about page 读取软件版本号2/n');
      bleModule['write']('0103FFEE0002942A', 0).then(() => { }).catch(err => {
        // alert('Sending failed');
      })
    };

    loadVersion();

    return () => {
      updateValueListener.remove();
    };
  }, []);

  useEffect(() => {
    const updateValueListener = bleModule.addListener(
      BleEventType.BleManagerDidUpdateValueForCharacteristic,
      handleUpdateValue,
    );
    const loadVersion = async () => {
      await fun2();
      console.log('about page 读取软件版本号2/n');
      bleModule['write']('0103FFEE0002942A', 0).then(() => { }).catch(err => {
        // alert('Sending failed');
      })
    };

    loadVersion();

    return () => {
      updateValueListener.remove();
    };
  }, []);

  /** 接收到新数据 */
  function handleUpdateValue(data: any) {
    let avalue: Array<number> = data.value;

    if (avalue.length == 9 && avalue[0] == 1 && csversion == 'unknown') {
      setCsversion((avalue[3] - 48) + '' + (avalue[4] - 48) + '' + (avalue[5] - 48) + '' + (avalue[6] - 48));
    }
  };
  React.useLayoutEffect(() => {
    navigation.setOptions({
      headerLeft: () => (
        <TouchableOpacity
          onPress={() => { }}
          style={{ paddingHorizontal: 15 }}>
          {
            deviceId ? <View>
              <Image
                source={require('../images/left_blue.png')}
                style={{ height: 24, width: 24 }}
              />
            </View> : null
          }
        </TouchableOpacity>
      ),
      // headerRight: () => (
      //   <TouchableOpacity
      //     onPress={() => { }}
      //     style={{ paddingHorizontal: 15 }}>
      //     {
      //       deviceId ? <View>
      //         <Image
      //           source={require('../images/right_edit.png')}
      //           style={{ height: 24, width: 24 }}
      //         />
      //       </View> : null
      //     }

      //   </TouchableOpacity>
      // ),
    });
  }, [navigation, deviceId]);

  const renderSetItem = ({ item, index }) => (
    <ItemHRow
      key={item.id}
      data={item}
      clickAction={() => clickAtIndex(index)}
    />
  );

  function isUpdate(version1, version2) {
    let arr1 = version1.split('.');
    let arr2 = version2.split('.');
    for (let i = 0; i < arr1.length;) {
      if (arr1[i] == arr2[i]) {
        i++
      } else {
        if (arr1[i] < arr2[i]) {
          return true;
        } else {
          return false;
        }
      }
    }
    return false;
  }

  async function getControllerVersion() {
    if (!deviceId) {
      showMessage({
        message: 'Not connected',
        type: 'warning',
        icon: 'warning',
        duration: 2000,
      });
      return;
    }

    let tmpStr = '';
    if (csversion === 'unknown') {
      tmpStr = 'all';
    } else {
      tmpStr = allData[0] ? allData[0][24].toString() : 'all';
    }

    return fetch('https://apifoxmock.com/m1/3367046-647647-default/binUpdate' + tmpStr)
      .then((response) => response.json())
      .then((responseJson) => {
        if (csversion == (responseJson.binUrl[0].vNew).toString()) {
          showMessage({
            message: 'No new version.',
            type: 'info',
            icon: 'info',
            duration: 2000,
          });
          return;
        }

        if (responseJson && responseJson.binUrl.length) {
          // 需要更新
          setUpState(1);
          setUpdateArr(responseJson.binUrl);
        } else {
          // 已是最新版本
          showMessage({
            message: 'No new version.',
            type: 'info',
            icon: 'info',
            duration: 2000,
          });
        }
      }).catch((error) => {
        console.error(error);
        showMessage({
          message: 'Network error, please try again later.',
          type: 'danger',
          icon: 'warning',
          duration: 2000,
        });
      });
  }

  async function getVersion() {

    return fetch('https://apifoxmock.com/m1/3367046-647647-default/appUpdate')
      .then((response) => response.json())
      .then((responseJson) => {

        let version1 = VersionNumber.appVersion;
        // console.log('当前 version:', responseJson)
        // console.log('应用市场 version:', responseJson.newVersion)
        let version2 = responseJson.newVersion;

        if (isUpdate(version1, version2)) {
          // 应用市场存在  且 当前版本 小于应用市场版本  跳转应用市场
          if (Platform.OS === 'ios') {
            Linking.openURL('https://apps.apple.com/cn/app/daymak-drive-2/id6473576810').catch(err => console.error('An error occurred', err));
          } else {
            Linking.openURL(`https://play.google.com/store/apps/details?id=com.rawrrdriver`).catch(err => console.error('An error occurred', err));
          }
        } else {
          // 已是最新版本
          showMessage({
            message: 'No new version.',
            type: 'info',
            icon: 'info',
            duration: 2000,
          });
        }
      }).catch((error) => {
        console.error(error);
        showMessage({
          message: 'Network error, please try again later.',
          type: 'danger',
          icon: 'warning',
          duration: 2000,
        });
      });
  }

  const fun = () => {
    return new Promise(resolve => {
      setTimeout(() =>
        resolve(''), 200);
    })
  }

  const fun4 = () => {
    return new Promise(resolve => {
      setTimeout(() =>
        resolve(''), 70);
    })
  }

  const fun2 = () => {
    return new Promise(resolve => {
      setTimeout(() =>
        resolve(''), 400);
    })
  }

  const fun3 = () => {
    return new Promise(resolve => {
      setTimeout(() =>
        resolve(''), 1100);
    })
  }

  const fun5 = () => {
    return new Promise(resolve => {
      setTimeout(() =>
        resolve(''), 1000);
    })
  }

  const crc16 = (data) => {
    let crcValue = 0xFFFF;
    for (let i = 0; i < data.length; i++) {
      crcValue ^= data[i] & 0xFFFF
      for (let j = 0; j < 8; j++) {
        if (crcValue & 0x0001) {
          crcValue >>= 1
          crcValue ^= 0xA001
        } else {
          crcValue >>= 1
        }
      }
    }

    crcValue = (Array(4).join('0') + crcValue.toString(16)).slice(-4);
    let crcArr = new Array(2)
    crcArr[0] = crcValue.substring(2, 4)
    crcArr[1] = crcValue.substring(0, 2)
    return crcArr;
  }

  function calcCRC16(ptr) {
    let crc = 0;
    for (let i = 0; i < ptr.length; i++) {
      crc ^= ptr[i] << 8;
      for (let j = 0; j < 8; j++) {
        if ((crc & 0x8000) !== 0) {
          crc = (crc << 1) ^ 0x1021;
        } else {
          crc <<= 1;
        }
      }
    }
    // return crc & 0xffff;


    // let crcValue = (crc & 0xffff).toString(16)
    let crcValue = (Array(4).join(0) + (crc & 0xffff).toString(16)).slice(-4)
    let crcArr = new Array(2)
    crcArr[0] = crcValue.substring(0, 2).toUpperCase()
    crcArr[1] = crcValue.substring(2, 4).toUpperCase()
    return crcArr;
  }

  const alert = (text) => {
    Alert.alert('', text, [{
      text: 'Ok', onPress: () => {
        bleModule.disconnect();
        disConnectDev();
        setCsversion('unknown');
        navigation.navigate('HomePage');
      }
    }]);
  }

  function strToHexCharCode(str) {
    if (str === "")
      return "";
    var hexCharCode = [];
    // hexCharCode.push("0x"); 
    for (var i = 0; i < str.length; i++) {
      hexCharCode.push((str.charCodeAt(i)).toString(16));
    }
    return hexCharCode.join("");
  }

  async function beginUpdate() {

    try {
      const config = RNFetchBlob.config({});
      const response = await config.fetch('GET', updateArr[selIndex]['vUrl']);
      const base64Str = response.base64();
      const formatValue = Buffer.from(base64Str, 'base64').toString('hex');
      // setUpdate(formatValue);
      setUpProgress(5);

      const updateHexStr = await formatValue;

      // 写入数据
      await writeData('0103FFEE0002942A');
      await fun5();
      await writeData('0103FFED0002642A');
      await fun4();
      await writeData('31');
      await fun4();

      for (let i = 0; i < 30; i++) {
        await writeData('31');
        setUpProgress(5 + (i + 1) / 5);
        await fun4();
      }

      await fun4();
      await writeData('31');
      await fun5();

      const nameStr = createNameStr(updateHexStr);
      const res = calcCRC16(Buffer.from(nameStr, "hex"));
      await writeData(`0100FF${nameStr}${res[0]}${res[1]}`);
      await fun5();

      for (let i = 1; i <= Math.ceil(updateHexStr.length / 256); i++) {
        const pian = updateHexStr.substring((i - 1) * 256, i * 256).padEnd(256, 'F').toUpperCase();
        const dd = Buffer.from(pian, "hex");
        const crcRes = calcCRC16(dd);
        const packet = createPacket(i, pian, crcRes);
        await writeData(packet);
        setUpProgress(11 + Math.ceil(i * 256 * 80 / updateHexStr.length));
        await fun();
      }

      await writeData('04');
      setUpProgress(92);
      await fun();

      const rename = ('0100FF').padEnd(256, '0');
      await writeData(rename);
      setUpProgress(95);
      await fun();

      await writeData('1818181818');
      setUpProgress(100);

      // 等待一段时间后执行重置操作

      setUpState(3);

      setTimeout(async () => {
        setUpState(4);
        setResetProgress(0);

        const tmpdata = resetMap[updateArr[selIndex]['vType']];
        for (let i = 0; i < tmpdata.length; i++) {
          setResetProgress(Math.round(i * 4.545));
          const tmpData = tmpdata[i].map(element => (Array(2).join(0) + element.toString(16)).slice(-2)).join('');
          await writeData(tmpData);
          await fun3();
        }

        await writeData('0110021E000200000000009B8F');
        setResetProgress(100);
        await fun2();
        changeHadUpdate(false);
        setUpState(5);
      }, 30000);

    } catch (err) {
      console.error('Error during update:', err);
      changeHadUpdate(false);
      setUpState(0);
      alert('Sending failed,Please reconnect');
    }
  }

  // 辅助函数
  async function writeData(data) {
    return new Promise<void>((resolve, reject) => {
      bleModule['write'](data, 0).then(() => {
        resolve();
      }).catch(err => {
        console.error('Error writing data:', err);
        reject(err);
      });
    });
  }

  function createNameStr(updateHexStr) {
    const name = 'S18ABZIPM_DingTu9_V2.3.0.2.bin';
    const length = (updateHexStr.length / 2).toString(16);
    return (Buffer.from(name).toString('hex') + '00' + length).padEnd(256, '0');
  }

  function createPacket(index, pian, crcRes) {
    const idxHex = (Array(2).join(0) + (index % 256).toString(16)).slice(-2).toUpperCase();
    const invIdxHex = (Array(2).join(0) + (255 - index % 256).toString(16)).slice(-2).toUpperCase();
    return `01${idxHex}${invIdxHex}${pian}${crcRes[0]}${crcRes[1]}`;
  }

  function clickAtIndex(index) {
    switch (index) {
      case 0:
        {
          if (csversion == 'unknown') {
            // 获取版本号
            bleModule['write']('0103FFEE0002942A', 0);
          }
          // bleModule.disconnect();
          // disConnectDev();
          // setCsversion('unknown');
          // IdleTimerManager.setIdleTimerDisabled(false);
          // navigation.navigate('HomePage');
        }
        break;
      case 1:
        break;
      case 2:
        // 控制器更新
        changeHadUpdate(true);
        getControllerVersion();
        break;
      case 3:
        // app更新  跳转应用市场
        getVersion();
        break;
      case 4:
        navigation.navigate('AboutMyPage')
        break;
      case 5:
        navigation.navigate('AboutUsPage')
        break;
    }
  }

  return (
    <View style={{ flex: 1, alignItems: 'center', backgroundColor: '#DDDDDD' }}>
      {/* <Spinner
        visible={showSpinner}
        textContent={'Updating...'}
        textStyle={{ color: '#FFF' }}
      /> */}
      <Image
        source={require('../images/bg_me.png')}
        style={{ width: '100%', alignItems: 'center', resizeMode: 'center' }}
      />
      <Image
        // source={require('../images/head_default.png')}
        source={headStr ? {
          uri: 'data:image/png;base64,' + headStr,
        } : require('../images/head_default.png')}
        style={{ height: 80, width: 80, marginTop: -160, borderRadius: 40 }}
      />
      <Text style={{ marginTop: 15, color: '#060606', fontSize: 16 }}>{nameStr}</Text>
      <ScrollView style={{ flex: 1, width: '100%', marginTop: 20 }} showsVerticalScrollIndicator={false}>
        {
          setArrData.map((item, index) => {
            return (renderSetItem({ item, index }))
          })
        }
      </ScrollView>
      <UpdateModal
        isVisible={upState}
        progress={upProgress}
        rprogress={resetProgress}
        updateArr={updateArr}
        onCancle={() => {
          setUpState(0);
        }}
        onSave={() => {
          setUpState(2);
          beginUpdate();
          IdleTimerManager.setIdleTimerDisabled(true);
        }}
        onEnd={() => {
          setUpState(0);
          // changeHadUpdate(false);
          bleModule.disconnect();
          disConnectDev();
          setCsversion('unknown');
          IdleTimerManager.setIdleTimerDisabled(false);
          navigation.navigate('HomePage');
        }}
        onSelBin={(binIndex) => {
          setSelIndex(binIndex)
        }}
      />
    </View>
  )
}

const mapStateToProps = ({
  device: {
    nameStr,
    deviceId,
    headStr,
    allData
  },
}) => ({
  nameStr,
  deviceId,
  headStr,
  allData
});

const enhance = compose(
  connect(mapStateToProps, {
    disConnectDev,
    changeHadUpdate
  }),
);
export default enhance(AboutPage);